package com.sky.AOP;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.entity.Employee;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Aspect
@Component
public class AutoFillAspect {

    @Before("@annotation(com.sky.annotation.AutoFill)")
    public void AutoFill(JoinPoint JoinPoint) {
        //获取MethodSignature并用Signature接口的类型封装(getSignature()方法返回的对象的引用类型是Signature,但是其本身是一个MethodSignature)
        Signature signature = JoinPoint.getSignature();
        //转化成 MethodSignature对象(即方法签名对象)以获取Method对象
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //获取被代理方法的AutoFill注解对象,并判断他是Insert类型的方法还是Update类型的方法
        AutoFill annotation = method.getAnnotation(AutoFill.class);
        //获取方法参数对象数组
        Object[] args = JoinPoint.getArgs();

        Class[] parameterTypes = methodSignature.getParameterTypes();

        if(annotation.value() == OperationType.UPDATE){
            try {
                //通过实体对象获取方法对象，并通过方法对象对实体对象进行修改
                Method updateTime = parameterTypes[0].getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method updateUser = parameterTypes[0].getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                updateTime.invoke(args[0], LocalDateTime.now());
                updateUser.invoke(args[0], BaseContext.getCurrentId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(annotation.value() == OperationType.INSERT){
            try {
                Method updateTime = args[0].getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method updateUser = args[0].getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                Method createTime = args[0].getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method createUser = args[0].getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                updateTime.invoke(args[0], LocalDateTime.now());
                updateUser.invoke(args[0], BaseContext.getCurrentId());
                createTime.invoke(args[0], LocalDateTime.now());
                createUser.invoke(args[0], BaseContext.getCurrentId());
            } catch (Exception e) {
            }
        }
    }
}
